#include "ym_json.h"

#include <iostream>
#include <sstream>

using namespace Ymsf::Infras;

YMJson::YMJson() :m_type(json_null)
{
}

YMJson::YMJson(bool value):m_type(json_bool)
{
	m_value.m_bool = value;
}

YMJson::YMJson(int value):m_type(json_int)
{
	m_value.m_int = value;
}

YMJson::YMJson(double value):m_type(json_double)
{
	m_value.m_double = value;
}

YMJson::YMJson(const char* value):m_type(json_string)
{
	m_value.m_string = new std::string(value);
}

YMJson::YMJson(const std::string& value):m_type(json_string)
{
	m_value.m_string = new std::string(value);
}

YMJson::YMJson(Type type) : m_type(type)
{
	switch (type)
	{
	case json_null:
		break;
	case json_bool:
		m_value.m_bool = false;
		break;
	case json_int:
		m_value.m_int = 0;
		break;
	case json_double:
		m_value.m_double = 0.0;
		break;
	case json_string:
		m_value.m_string = new std::string();
		break;
	case json_array:
		m_value.m_array = new std::vector<YMJson>();
		break;
	case json_object:
		m_value.m_object = new std::map<std::string, YMJson>();
		break;
	default:
		break;
	}
		
}

YMJson::YMJson(const YMJson& other):m_type(other.m_type),m_value(other.m_value)
{
}

YMJson::operator bool()
{
	return m_value.m_bool;
}

YMJson::operator int()
{
	return m_value.m_int;
}

YMJson::operator double()
{
	return m_value.m_double;
}

YMJson::operator std::string()
{
	return *(m_value.m_string);
}

YMJson& YMJson::operator[](int index)
{
	if (m_type != json_array)
	{
		m_type = json_array;
		m_value.m_array = new std::vector<YMJson>();
	}
	int size = (m_value.m_array)->size();
	if (index >= size)
	{
		for (int i = size; i <= index; i++)
		{
			(m_value.m_array)->push_back(YMJson());
		}
	}
	return (m_value.m_array)->at(index);
}

void YMJson::append(const YMJson & object)
{
	if (m_type != json_array)
	{
		m_type = json_array;
		m_value.m_array = new std::vector<YMJson>();
	}
	(m_value.m_array)->push_back(object);	
}

std::string YMJson::Str()
{
	std::stringstream ss;
	switch (m_type)
	{
	case json_null:
		ss << "null";
		break;
	case json_bool:
		if (m_value.m_bool)
		{
			ss << "true";
		}
		else
		{
			ss << "false";
		}
		break;
	case json_int:
		ss << m_value.m_int;
		break;
	case json_double:
		ss << m_value.m_double;
		break;
	case json_string:
		ss << '\"' << *(m_value.m_string) << '\"';
		break;
	case json_array:
	{
		ss << '[';
		for (auto iter=(m_value.m_array)->begin();iter!= (m_value.m_array)->end();iter++)
		{
			if (iter != (m_value.m_array)->begin())
			{
				ss << ',';
			}
			ss << iter->Str();
		}
		ss << ']';
		break;
	}
	case json_object:
	{
		ss << '{';
		for (auto iter = (m_value.m_object)->begin(); iter != (m_value.m_object)->end(); iter++)
		{
			if (iter != (m_value.m_object)->begin())
			{
				ss << ',';
			}
			ss << '\"'<<iter->first<<'\"'<<(iter->second).Str();
		}
		ss << '}';
		break;
	}

	default:
		break;
	}

	return ss.str();
}

YMJson& YMJson::operator[](const char* key)
{
	std::string name(key);
	return (*this)[name];
}

YMJson& YMJson::operator[](const std::string& key)
{
	return (*(m_value.m_object))[key];
}

void YMJson::operator=(const YMJson& other)
{
	m_type = other.m_type;
	m_value = other.m_value;
}

void YMJson::copy()
{
	std::cout << "hello world" << std::endl;
}


